package org.ccay.core.orm;

import java.util.List;
import java.util.regex.Pattern;

import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.session.Configuration;

import org.ccay.core.util.StringUtil;

/**
 * 扩充BoundSql对象, 用来处理&lt;addProgram &gt;Tag
 * @see org.ccay.core.orm.plugins.CdataTagInterceptor
 * @see org.ccay.core.orm.ExtendedSqlSource
 * 
 * @since 2011-12-14
 */
public class ExtendedBoundSql extends BoundSql {

	protected final static Pattern addProgram = Pattern.compile("<addProgram.+>");
	
	protected final static Pattern addOrderBy = Pattern.compile("<addOrderBy.+>");
	
	protected final static Pattern addFilter =  Pattern.compile("<addFilter[^>]*?((>.*?</addFilter>)|(/>))",Pattern.DOTALL);

	private BoundSql delegate;
	
	private String  catchSql = null;
	
	private String finalSql = null;
	
	public void setFinalSql(String finalSql) {
		this.finalSql = finalSql;
	}

	public ExtendedBoundSql(Configuration configuration, String sql,
			List<ParameterMapping> parameterMappings, Object parameterObject) {
		super(configuration, sql, parameterMappings, parameterObject);
	}

	public ExtendedBoundSql(Configuration configuration, BoundSql delegate) {
		super(configuration, delegate.getSql(),
				delegate.getParameterMappings(), delegate.getParameterObject());
		this.delegate = delegate;
	}

	/* (non-Javadoc)
	 * @see org.apache.ibatis.mapping.BoundSql#getAdditionalParameter(java.lang.String)
	 */
	@Override
	public Object getAdditionalParameter(String name) {
		return delegate.getAdditionalParameter(name);
	}

	/* (non-Javadoc)
	 * @see org.apache.ibatis.mapping.BoundSql#getParameterMappings()
	 */
	@Override
	public List<ParameterMapping> getParameterMappings() {
		return delegate.getParameterMappings();
	}

	@Override
	public Object getParameterObject() {
		return delegate.getParameterObject();
	}

	/* (non-Javadoc)
	 * @see org.apache.ibatis.mapping.BoundSql#getSql()
	 */
	@Override
	public String getSql() {
		if(!StringUtil.isNullOrEmpty(finalSql)){
			return finalSql;
		}
		if(!StringUtil.isNullOrEmpty(catchSql)){
			return catchSql;
		}
		String sql = delegate.getSql();
		//使用正则表达式判断 如果存在 那么就替换   如果不存在 或略  并记录到内存中
		if(sql.indexOf("<addProgram")!=-1){
			sql = StringUtil.replaceAll(sql, addProgram, new AddProgramCallback(
					getParameterObject()));
		}
		//使用正则表达式判断 如果存在 那么就替换   如果不存在 或略  并记录到内存中
		if(sql.indexOf("<addOrderBy")!=-1){
			//处理排序
			sql = StringUtil.replaceAll(sql, addOrderBy, new AddOrderByCallback(
				getParameterObject()));
		}
		//使用正则表达式判断 如果存在 那么就替换   如果不存在 或略  并记录到内存中
		if(sql.indexOf("<addFilter")!=-1){
			//处理排序
			sql = StringUtil.replaceAll(sql, addFilter, new AddFilterCallback(
				getParameterObject()));
		}
		catchSql = sql;
		return catchSql;
	}

	/* (non-Javadoc)
	 * @see org.apache.ibatis.mapping.BoundSql#hasAdditionalParameter(java.lang.String)
	 */
	@Override
	public boolean hasAdditionalParameter(String name) {
		return delegate.hasAdditionalParameter(name);
	}

	/* (non-Javadoc)
	 * @see org.apache.ibatis.mapping.BoundSql#setAdditionalParameter(java.lang.String, java.lang.Object)
	 */
	@Override
	public void setAdditionalParameter(String name, Object value) {
		delegate.setAdditionalParameter(name, value);
	}

}
